package org.acghub.config.reader;

import org.acghub.config.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

import java.io.File;

/**
 * @Desc
 * @Author miyuki4j
 * @Date 2025/7/25/星期五 10:25
 * @Version 1.0
 */
public abstract class AbstractExcelTableReader implements TableReader {
    @Override
    public TableMeta readMeta(File file) {
        try (Workbook workbook = newWorkbook(file)) {
            Sheet meta = workbook.getSheet("meta");
            if (meta == null) {
                throw new TableReadException("文件路径：" + file.getAbsolutePath() + "，没有meta表");
            }
            Sheet data = workbook.getSheet("data");
            if (data == null) {
                throw new TableReadException("文件路径：" + file.getAbsolutePath() + "，没有data表");
            }
            return readMeta(meta, data);
        } catch (Exception e) {
            throw new TableReadException("读取文件失败", e);
        }
    }

    @Override
    public TableData readData(File file) {

        TableData tableData;
        try (Workbook workbook = newWorkbook(file)) {
            Sheet meta = workbook.getSheet("meta");
            if (meta == null) {
                throw new TableReadException("文件路径：" + file.getAbsolutePath() + "，没有meta表");
            }
            Sheet data = workbook.getSheet("data");
            if (data == null) {
                throw new TableReadException("文件路径：" + file.getAbsolutePath() + "，没有data表");
            }
            final TableMeta tableMeta = readMeta(meta, data);
            tableData = new TableData(tableMeta);

            // 从第6行开始读取数据
            for (int i = 6; i <= tableMeta.getHeader().getRowNum(); i++) {
                Row dataRow = data.getRow(i);
                TableDataRow tableDataRow = new TableDataRow(i);
                for (TableField tableField : tableMeta.getHeader()) {
                    Cell cell = dataRow.getCell(tableField.getIndex());
                    String value = org.acghub.config.StringUtils.trim(readCellValue(cell));
                    tableDataRow.add(new TableDataCell(tableField.getIndex(), value));
                }
                if (tableDataRow.isContentEmpty()) {
                    continue;
                }
                tableData.add(tableDataRow);
            }
        } catch (Exception e) {
            throw new TableReadException("读取文件失败", e);
        }
        return tableData;
    }

    private String readCellValue(Cell cell) {
        if (cell == null) {
            return "";
        }
        return switch (cell.getCellType()) {
            case NUMERIC -> String.valueOf(cell.getNumericCellValue());
            case STRING -> cell.getStringCellValue();
            case FORMULA -> cell.getCellFormula();
            case BLANK -> "";
            case BOOLEAN -> String.valueOf(cell.getBooleanCellValue());
            case ERROR -> String.valueOf(cell.getErrorCellValue());
            default -> throw new TableReadException("不支持的Cell类型, type=" + cell.getCellType());
        };
    }


    private TableMeta readMeta(Sheet meat, Sheet data) {
        String module = meat.getRow(1).getCell(0).getStringCellValue();
        String tableName = meat.getRow(1).getCell(2).getStringCellValue();
        TableHeader tableHeader = readHeader(data);
        return new TableMeta(module, tableName, tableHeader);
    }

    private TableHeader readHeader(Sheet data) {
        Row firstRow = data.getRow(0);
        final int rowNum = data.getLastRowNum();
        final int columnNum = firstRow.getLastCellNum();
        TableHeader tableHeader = new TableHeader(rowNum, columnNum);
        for (int i = 0; i < columnNum; i++) {
            String export = StringUtils.trim(data.getRow(3).getCell(i).getStringCellValue());
            if (!StringUtils.contains(export, "s")) {
                continue;
            }
            String comment = StringUtils.trim(data.getRow(0).getCell(i).getStringCellValue());
            String name = StringUtils.trim(data.getRow(1).getCell(i).getStringCellValue());
            String type = StringUtils.trim(data.getRow(2).getCell(i).getStringCellValue());
            String delimiters = "";
            Cell delimitersCell = data.getRow(4).getCell(i);
            if (delimitersCell != null) {
                delimiters = StringUtils.trim(delimitersCell.getStringCellValue());
            }
            tableHeader.add(new TableField(i, comment, name, type, delimiters));
        }
        return tableHeader;
    }

    protected abstract Workbook newWorkbook(File file) throws Exception;
}
